﻿using System;
using System.IO;
using System.Text;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using CustomerContactSystem.Core.Model;
using NHibernate;
using NHibernate.Criterion;

namespace CustomerContactSystem.WebForms.Customers
{
    public partial class Search : BasePage {
        private string _optionsHeaderId = "";
        private const int PageSize = 20;      
        public int CurrentPage {
            get {return Request.QueryString["page"] != null ? int.Parse(Request.QueryString["page"]) : 1;}
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsValidPageRequest(true, true, "")) {
                return;
            }            

            if (Request.QueryString["view"] != null) {
                FindCustomers();
                Response.Clear();
                Response.AddHeader("content-disposition", "attachment;filename=Customers.xls");
                Response.Charset = "";
                Response.ContentType = "application/vnd.ms-xls";
                var stringWriter = new StringWriter();
                var htmlWriter = new HtmlTextWriter(stringWriter);
                CustomerList.RenderControl(htmlWriter);
                Response.Write(stringWriter.ToString());
                Response.End();
            }
            else
            {
                SetValuesFromQueryString();
                ExcelLink.NavigateUrl = "~/Customers/Search.aspx?" + GetQueryString() + "&view=excel";
                CreateNewLink.NavigateUrl = "~/Customers/Create.aspx?" + GetQueryString();
                FindCustomers();
                if (Request.QueryString.Count > 0)
                {
                    SearchForm.Attributes.Add("class", "search-form collapsed");
                }
            }
        }

        private void SetValuesFromQueryString() {
            FirstName.Text = QueryStringOrEmpty("firstname");
            SecondName.Text = QueryStringOrEmpty("secondname");
            Address.Text = QueryStringOrEmpty("address");
            ContactableOnly.Checked = QueryStringOrFalse("contactable");
        }

        private void FindCustomers() {
            var customers = CustomerRepository.QueryOver();
            if (QueryStringOrEmpty("firstname").Length > 0) {

                customers = customers.WhereRestrictionOn(c => c.FirstName).IsLike(QueryStringOrEmpty("firstname").ToLower(), MatchMode.Anywhere);
            }

            if (QueryStringOrEmpty("secondname").Length > 0) {
                customers = customers.WhereRestrictionOn(c => c.SecondName).IsLike(QueryStringOrEmpty("secondname").ToLower(), MatchMode.Anywhere);
            }

            if (QueryStringOrEmpty("address").Length > 0) {
                customers = customers.WhereRestrictionOn(c => c.Address1).IsLike(QueryStringOrEmpty("address").ToLower(), MatchMode.Anywhere);
            }

            if (QueryStringOrFalse("contactable")) {
                customers = customers.Where(c => c.CanBeContactedForFeedback);
            }

            customers = customers.OrderBy(c => c.SecondName).Asc.ThenBy(c => c.FirstName).Asc;

            if (Request.QueryString["view"] == null) {
                CustomerList.DataSource = customers.Skip((CurrentPage - 1) * PageSize).Take(PageSize).List();
                var totalRecords =
                    CriteriaTransformer.TransformToRowCount(customers.UnderlyingCriteria).UniqueResult<int>();
                SetupPaging(totalRecords);
            }
            else {
                CustomerList.DataSource = customers.List();
            }
            
            CustomerList.DataBind();
        }

        private string GetQueryString() {
            var sb = new StringBuilder();
            sb.Append("firstname=" + FirstName.Text);
            sb.Append("&secondname=" + SecondName.Text);
            sb.Append("&address=" + Address.Text);
            sb.Append("&contactable=" + ContactableOnly.Checked);
            return sb.ToString();
        }

        private void SetupPaging(int totalRecords) {
            if (totalRecords == 0) {
                SearchResultMessage.Text = "No Customers Found!";
            }
            else if (totalRecords <= PageSize)
            {
                PagingList.Visible = false;
            }
            else
            {
                var totalPages = (int)Math.Ceiling((double)totalRecords / PageSize);
                var previousPageNumber = CurrentPage - 1;
                if (previousPageNumber < 1)
                    previousPageNumber = 1;
                var nextPageNumber = CurrentPage + 1;
                if (nextPageNumber > totalPages)
                    nextPageNumber = totalPages;

                FirstLink.NavigateUrl = "~/Customers/Search.aspx?" + GetQueryString();
                PreviousLink.NavigateUrl = "~/Customers/Search.aspx?" + GetQueryString() + "&page=" + previousPageNumber;
                NextLink.NavigateUrl = "~/Customers/Search.aspx?" + GetQueryString() + "&page=" + nextPageNumber;
                LastLink.NavigateUrl = "~/Customers/Search.aspx?" + GetQueryString() + "&page=" + totalPages;

                PagingInfo.Text = "Page " + CurrentPage + " of " + totalPages + " (" + totalRecords + " customers)";
            }
        }

        protected void SearchCustomersClick(object sender, EventArgs e) {
            Response.Redirect("~/Customers/Search.aspx?" + GetQueryString());
        }

        protected void CustomerListItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Header) {
                var optionsHeader = (HtmlTableCell) e.Item.FindControl("OptionsHeader");
                _optionsHeaderId = optionsHeader.ClientID;

                if (Request.QueryString["view"] != null) {
                    optionsHeader.Visible = false;
                }
            }

            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) {
                return;
            }
            var rowCustomer = (Customer)e.Item.DataItem;
            var nameCell = (HtmlTableCell)e.Item.FindControl("NameCell");
            var addressCell = (HtmlTableCell)e.Item.FindControl("AddressCell");
            var contactableCell = (HtmlTableCell)e.Item.FindControl("ContactableCell");
            var optionsCell = (HtmlTableCell)e.Item.FindControl("OptionsCell");
            var useInNewEnquiryLink = (HyperLink)e.Item.FindControl("UseInNewEnquiryLink");
            var viewEnquiriesLink = (HyperLink)e.Item.FindControl("ViewEnquiriesLink");
            var editCustomerLink = (HyperLink)e.Item.FindControl("EditCustomerLink");

            if (Request.QueryString["view"] != null) {
                optionsCell.Visible = false;
                nameCell.Attributes.Add("style", "vertical-align:top;border: 1px solid #000;");
                addressCell.Attributes.Add("style", "vertical-align:top;border: 1px solid #000;");
                contactableCell.Attributes.Add("style", "vertical-align:top;border: 1px solid #000;");
            }
            else {
                optionsCell.Attributes.Add("header", _optionsHeaderId);
                useInNewEnquiryLink.NavigateUrl = "~/Enquiries/Create2.aspx?customer=" + rowCustomer.Id;
                viewEnquiriesLink.NavigateUrl = "~/Enquiries/Customers/Enquiries.aspx?customerid=" + rowCustomer.Id;
                editCustomerLink.NavigateUrl = "~/Customers/Edit.aspx?id=" + rowCustomer.Id + "&" + GetQueryString();
            }
        }
    }
}